/*
 * Tic-Tac-Toe - Turn-based strategy game
 * Copyright 2008, 2009 Shayne Riley and Paul Maseberg
 *
 * Tic-Tac-Toe is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Tic-Tac-Toe is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Tic-Tac-Toe.  If not, see <http://www.gnu.org/licenses/>
 * or write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * To contact the authors on questions or issues regarding the license,
 * you may send an email to <shayner at gmail dot com>
 */

#include <map>
#include <SDL/SDL.h>
#include <SDL/SDL_mixer.h>

#ifndef AUDIO_H_
#define AUDIO_H_

/**
 * The Audio system which plays sound clips and songs.
 */
class Audio
{
public:

    /** Short sounds to play */
    enum Clip
    {
        CLIP_X,  ///< Play when X is placed.
        CLIP_O   ///< Play when O is placed.
    };
    enum Song
    {
        SONG_TITLE,  ///< Play when the title screen appears.
        SONG_WIN,  ///< Play when the player wins.
        SONG_LOSE,  ///< Play when the player loses.
        SONG_CAT,  ///< Play when the player ties.
        SONG_SECRET  ///< Play when the secret conditions are met! I wonder...
    };

    /**
     * Constructs the audio system. Initializes the sounds that are used.
     */
    Audio();

    virtual ~Audio();

    /** Play a sound clip. They can be overlapping and play on top of music. */
    void play(Clip clip);

    /** Play music. Only one song is played at a time but can be interrupted. */
    void play(Song song);

    /** Stop any music that is currently playing. */
    void stopSong();
private:
    /**
     * Loads a sound clip from the null-terminated string. Ogg Vorbis or WAV.
     *
     * @param inFile The filename, either absolute or relative.
     * @param clip  The clip to associate the sound to.
     * @return true on success, or false and an error message on failure.
     */
    bool load(const char *inFile, Clip clip);

    /**
     * Loads a song from the null-terminated string. Ogg Vorbis or WAV.
     *
     * @param inFile The filename, either absolute or relative.
     * @param song  The song to associate the sound to.
     * @return true on success, or false and an error message on failure.
     */
    bool load(const char *inFile, Song song);

    /**
     * Unloads the sound clip, releasing any memory.
     * @param clip  The clip to unload.
     */
    void unload(Clip clip);

    /**
     * Unloads the song, releasing any memory.
     * @param song  The song to unload.
     */
    void unload(Song song);

    std::map<Clip, Mix_Chunk *> clips;
    std::map<Song, Mix_Music *> songs;

    /// @brief Samples per second to play audio.
    static const int AUDIO_RATE = 44100;
    /// @brief Determines size of each sample and endianness.
    static const Uint16 AUDIO_FORMAT = AUDIO_S16SYS;
    /// @brief Number of sounds that can be played at the same time.
    static const int AUDIO_CHANNELS = 2;
    /// @brief Maximum size of the audio buffers in bytes.
    static const int AUDIO_BUFFER_SIZE = 2048;
};

#endif /* AUDIO_H_ */
